﻿using DBUtil.FastEntity.Annotations;
using DBUtil.FastEntity.Builders;
using DotNetCommon.Extensions;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;

namespace DBUtil.FastEntity
{
    public class ExpressionParser
    {
        private Dictionary<ExpressionType, string> _dicOp = new Dictionary<ExpressionType, string>()
        {
            { ExpressionType.Not,"not" },
            { ExpressionType.AndAlso,"and" },
            { ExpressionType.OrElse,"or" },
            { ExpressionType.GreaterThan,">" },
            { ExpressionType.NotEqual,"<>" },
            { ExpressionType.GreaterThanOrEqual,">=" },
            { ExpressionType.LessThan,"<" },
            { ExpressionType.LessThanOrEqual,"<=" },
            { ExpressionType.Add,"+" },
            { ExpressionType.Subtract,"-" },
            { ExpressionType.Multiply,"*" },
            { ExpressionType.Divide,"/" },
            { ExpressionType.Modulo,"%" },
        };

        private Dictionary<ExpressionType, Action<ExpressionParseContext>> _dicActs = new Dictionary<ExpressionType, Action<ExpressionParseContext>>();

        public ExpressionParser()
        {
            _dicActs.Add(ExpressionType.AndAlso, VisitAndAlso);
            _dicActs.Add(ExpressionType.OrElse, VisitOrElse);
            _dicActs.Add(ExpressionType.Not, VisitNot);
            _dicActs.Add(ExpressionType.GreaterThan, VisitBinary);
            _dicActs.Add(ExpressionType.GreaterThanOrEqual, VisitBinary);
            _dicActs.Add(ExpressionType.LessThan, VisitBinary);
            _dicActs.Add(ExpressionType.LessThanOrEqual, VisitBinary);
            _dicActs.Add(ExpressionType.Add, VisitBinary);
            _dicActs.Add(ExpressionType.Subtract, VisitBinary);
            _dicActs.Add(ExpressionType.Multiply, VisitBinary);
            _dicActs.Add(ExpressionType.Divide, VisitBinary);
            _dicActs.Add(ExpressionType.Modulo, VisitBinary);

            _dicActs.Add(ExpressionType.Constant, VisitConstant);

            _dicActs.Add(ExpressionType.Parameter, VisitParameter);
            _dicActs.Add(ExpressionType.MemberAccess, VisitMemberAccess);
        }

        #region BuildTree 构建表达式树
        /// <summary>
        /// 先遍历表达式树构建上下文环境(主要识别哪个分支里面带有Parameter)
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public ExpressionParseContext BuildTree(Expression expression)
        {
            var lambda = (expression as LambdaExpression);
            if (lambda.Parameters.Count != 1) throw new Exception("lambda表达式必须有且只有一个参数!");
            var alias = lambda.Parameters.FirstOrDefault().Name;
            var ctx = new ExpressionParseContext()
            {
                Expression = lambda,
                SelfHasParameter = true,
                SelfAlias = alias,
                SelfParameter = lambda.Parameters.FirstOrDefault()
            };
            var newCtx = new ExpressionParseContext()
            {
                Expression = lambda.Body
            };
            newCtx.Parents.Add(ctx);
            ctx.Children.Add(newCtx);
            _buildTree(newCtx);
            return ctx;
            //可以对表达式树整体做缓存(注意缓存的是什么，中间涉及到局部变量，Parameter在缓存中是怎么处理的,不缓存求值后的表达式，缓存求值前的表达式，并且要知道直接去求值)
            //第一步，先遍历表达式树构建上下文环境(主要识别哪个分支里面带有Parameter)
            //第二步，将没有Parameter的分支进行求值，求值后简化表达式树(包括对MemberAccess的求值)
        }

        private void _buildTree(ExpressionParseContext ctx)
        {
            if (IsBinary(ctx.Expression))
            {
                var exp = ctx.Expression as BinaryExpression;
                var newCtx = new ExpressionParseContext()
                {
                    Expression = exp.Left
                };
                newCtx.Parents.AddRange(ctx.Parents);
                newCtx.Parents.Add(ctx);
                ctx.Children.Add(newCtx);
                _buildTree(newCtx);
                newCtx = new ExpressionParseContext()
                {
                    Expression = exp.Right
                };
                newCtx.Parents.AddRange(ctx.Parents);
                newCtx.Parents.Add(ctx);
                ctx.Children.Add(newCtx);
                _buildTree(newCtx);
            }
            else if (IsUnary(ctx.Expression))
            {
                var exp = ctx.Expression as UnaryExpression;
                var newCtx = new ExpressionParseContext()
                {
                    Expression = exp.Operand
                };
                newCtx.Parents.AddRange(ctx.Parents);
                newCtx.Parents.Add(ctx);
                ctx.Children.Add(newCtx);
                _buildTree(newCtx);
            }
            else if (IsConditional(ctx.Expression))
            {
                var exp = ctx.Expression as ConditionalExpression;
                var newCtx = new ExpressionParseContext()
                {
                    Expression = exp.Test
                };
                newCtx.Parents.AddRange(ctx.Parents);
                newCtx.Parents.Add(ctx);
                ctx.Children.Add(newCtx);
                _buildTree(newCtx);
                newCtx = new ExpressionParseContext()
                {
                    Expression = exp.IfTrue
                };
                newCtx.Parents.AddRange(ctx.Parents);
                newCtx.Parents.Add(ctx);
                ctx.Children.Add(newCtx);
                _buildTree(newCtx);
                newCtx = new ExpressionParseContext()
                {
                    Expression = exp.IfFalse
                };
                newCtx.Parents.AddRange(ctx.Parents);
                newCtx.Parents.Add(ctx);
                ctx.Children.Add(newCtx);
                _buildTree(newCtx);
            }
            else if (ctx.NodeType == ExpressionType.Convert) { }//也属于UnaryExpression
            else if (ctx.NodeType == ExpressionType.Call)
            {
                var exp = ctx.Expression as MethodCallExpression;
                var newCtx = new ExpressionParseContext()
                {
                    Expression = exp.Object
                };
                newCtx.Parents.AddRange(ctx.Parents);
                newCtx.Parents.Add(ctx);
                ctx.Children.Add(newCtx);
                //当调用实例方法时才需要向下遍历
                if (exp.Object != null) _buildTree(newCtx);

                foreach (var arg in exp.Arguments)
                {
                    newCtx = new ExpressionParseContext()
                    {
                        Expression = arg
                    };
                    newCtx.Parents.AddRange(ctx.Parents);
                    newCtx.Parents.Add(ctx);
                    ctx.Children.Add(newCtx);
                    _buildTree(newCtx);
                }
            }
            else if (ctx.NodeType == ExpressionType.Constant || ctx.NodeType == ExpressionType.Parameter)
            {
                //到达终点
                if (ctx.NodeType == ExpressionType.Parameter && ctx.Expression == ctx.Parameter)
                {
                    ctx.SelfHasParameter = true;
                }
                return;
            }
            else if (ctx.NodeType == ExpressionType.MemberAccess)
            {
                var exp = ctx.Expression as MemberExpression;
                var newCtx = new ExpressionParseContext()
                {
                    Expression = exp.Expression
                };
                newCtx.Parents.AddRange(ctx.Parents);
                newCtx.Parents.Add(ctx);
                ctx.Children.Add(newCtx);
                _buildTree(newCtx);
            }
            else if (ctx.NodeType == ExpressionType.ListInit)
            {
                var exp = ctx.Expression as ListInitExpression;
                foreach (var item in exp.Initializers)
                {
                    var newCtx = new ExpressionParseContext()
                    {
                        Expression = item.Arguments[0]
                    };
                    newCtx.Parents.AddRange(ctx.Parents);
                    newCtx.Parents.Add(ctx);
                    ctx.Children.Add(newCtx);
                    _buildTree(newCtx);
                }
            }
            else if (ctx.NodeType == ExpressionType.NewArrayInit)
            {
                var exp = ctx.Expression as NewArrayExpression;
                foreach (var item in exp.Expressions)
                {
                    var newCtx = new ExpressionParseContext()
                    {
                        Expression = item
                    };
                    newCtx.Parents.AddRange(ctx.Parents);
                    newCtx.Parents.Add(ctx);
                    ctx.Children.Add(newCtx);
                    _buildTree(newCtx);
                }
            }
            else if (ctx.NodeType == ExpressionType.Lambda)
            {
                //exp2 = i => list.Select(j => j.Id).Contains(i.Int);
                var exp = ctx.Expression as LambdaExpression;
                exp.Parameters.ForEach(p =>
                {
                    var newCtx = new ExpressionParseContext()
                    {
                        Expression = p
                    };
                    newCtx.Parents.AddRange(ctx.Parents);
                    newCtx.Parents.Add(ctx);
                    ctx.Children.Add(newCtx);
                    _buildTree(newCtx);
                });
                var newCtx = new ExpressionParseContext()
                {
                    Expression = exp.Body
                };
                newCtx.Parents.AddRange(ctx.Parents);
                newCtx.Parents.Add(ctx);
                ctx.Children.Add(newCtx);
                _buildTree(newCtx);

            }
            else
            {
                throw new Exception($"无法识别的表达式:{ctx.Expression}");
            }
        }
        #endregion

        #region 裁剪表达式树
        /// <summary>
        /// 裁剪表达式树(把没有参数参与的分支求出最终值)
        /// </summary>
        /// <param name="ctx"></param>
        public void PruneTree(ExpressionParseContext ctx)
        {
            //先计算非参数表达式
            _pruneTree_Calc(ctx.Children.FirstOrDefault());
            //对于逻辑运算符简化 (xx and true等)
            _pruneTree_Logic(ctx);
            //裁剪顶端的

        }

        private void _pruneTree_Logic(ExpressionParseContext ctx)
        {
            if (ctx.Children.Count > 0)
            {
                for (var i = ctx.Children.Count - 1; i >= 0; i--)
                {
                    _pruneTree_Logic(ctx.Children[i]);
                }
                if (ctx.NodeType == ExpressionType.AndAlso || ctx.NodeType == ExpressionType.OrElse)
                {
                    var isOneConstant = ctx.Children[0].NodeType == ExpressionType.Constant;
                    var isTwoConstant = ctx.Children[1].NodeType == ExpressionType.Constant;
                    if (isOneConstant && isTwoConstant)
                    {
                        var val1 = (ctx.Children[0].Expression as ConstantExpression).Value.To<bool>();
                        var val2 = (ctx.Children[1].Expression as ConstantExpression).Value.To<bool>();
                        if (ctx.NodeType == ExpressionType.AndAlso)
                        {
                            var val = val1 && val2;
                            var index = ctx.Parent.Children.IndexOf(ctx);
                            ctx.Parent.Children.RemoveAt(index);
                            var constExp = LambdaExpression.Constant(val);
                            var newCtx = new ExpressionParseContext()
                            {
                                Expression = constExp,
                                Parents = ctx.Parents
                            };
                            ctx.Parent.Children.Insert(index, newCtx);
                            return;
                        }
                        else
                        {
                            var val = val1 || val2;
                            var index = ctx.Parent.Children.IndexOf(ctx);
                            ctx.Parent.Children.RemoveAt(index);
                            var constExp = LambdaExpression.Constant(val);
                            var newCtx = new ExpressionParseContext()
                            {
                                Expression = constExp,
                                Parents = ctx.Parents
                            };
                            ctx.Parent.Children.Insert(index, newCtx);
                            return;
                        }
                    }
                    else if (isOneConstant || isTwoConstant)
                    {
                        //仅isOneConstant
                        var val = (ctx.Children[isOneConstant ? 0 : 1].Expression as ConstantExpression).Value.To<bool>();
                        if (val && ctx.NodeType == ExpressionType.OrElse)
                        {
                            //短路或
                            var index = ctx.Parent.Children.IndexOf(ctx);
                            ctx.Parent.Children.RemoveAt(index);
                            var constExp = LambdaExpression.Constant(true);
                            var newCtx = new ExpressionParseContext()
                            {
                                Expression = constExp,
                                Parents = ctx.Parents
                            };
                            ctx.Parent.Children.Insert(index, newCtx);
                            return;
                        }
                        else if ((!val) && ctx.NodeType == ExpressionType.AndAlso)
                        {
                            //短路与
                            var index = ctx.Parent.Children.IndexOf(ctx);
                            ctx.Parent.Children.RemoveAt(index);
                            var constExp = LambdaExpression.Constant(false);
                            var newCtx = new ExpressionParseContext()
                            {
                                Expression = constExp,
                                Parents = ctx.Parents
                            };
                            ctx.Parent.Children.Insert(index, newCtx);
                            return;
                        }
                    }
                }
                else if (ctx.NodeType == ExpressionType.Not)
                {
                    if (ctx.Children[0].NodeType == ExpressionType.Constant)
                    {
                        //简化反运算
                        var val = (ctx.Children[0].Expression as ConstantExpression).Value.To<bool>();
                        var index = ctx.Parent.Children.IndexOf(ctx);
                        ctx.Parent.Children.RemoveAt(index);
                        var constExp = LambdaExpression.Constant(!val);
                        var newCtx = new ExpressionParseContext()
                        {
                            Expression = constExp,
                            Parents = ctx.Parents
                        };
                        ctx.Parent.Children.Insert(index, newCtx);
                        return;
                    }
                }
                else if (ctx.NodeType == ExpressionType.Lambda)
                {
                    if (ctx.Children[0].NodeType == ExpressionType.Constant)
                    {
                        var flag = (ctx.Children[0].Expression as ConstantExpression).Value.To<bool>();
                        var constExp = LambdaExpression.Constant(flag);
                        var newCtx = new ExpressionParseContext()
                        {
                            Expression = constExp,
                            Parents = ctx.Parents
                        };
                        if (ctx.Parent == null)
                        {
                            ctx.Expression = constExp;
                        }
                        else
                        {
                            var index = ctx.Parent.Children.IndexOf(ctx);
                            ctx.Parent.Children.Insert(index, newCtx);
                        }
                    }
                }
            }
        }

        private void _pruneTree_Calc(ExpressionParseContext ctx)
        {
            if (ctx.HasParameter)
            {
                for (var i = ctx.Children.Count - 1; i >= 0; i--)
                {
                    _pruneTree_Calc(ctx.Children[i]);
                }
                if (ctx.NodeType == ExpressionType.Conditional)
                {
                    //三元运算符可以在子节点修剪后再修剪
                    if (ctx.Children[0].NodeType == ExpressionType.Constant)
                    {
                        //可以简化
                        var test = ctx.Children[0].Expression as ConstantExpression;
                        var isTrue = test.Value.To<bool>();
                        ExpressionParseContext newCtx = null;
                        if (isTrue)
                        {
                            newCtx = ctx.Children[1];
                        }
                        else
                        {
                            newCtx = ctx.Children[2];
                        }
                        var constCtx = newCtx;
                        constCtx.Parents.Clear();
                        constCtx.Parents.AddRange(ctx.Parents);
                        var index = ctx.Parent.Children.IndexOf(ctx);
                        ctx.Parent.Children.Remove(ctx);
                        ctx.Parent.Children.Insert(index, constCtx);
                    }
                }
            }
            else
            {
                //从这里开始往下都没有参数,所以求出具体值,替换表达式中的节点
                object obj = null;
                ConstantExpression exp = null;
                //当call调用静态方法时 存在expression为null情况
                if (ctx.Expression == null)
                {
                    exp = Expression.Constant(null, typeof(object));
                }
                else
                {
                    var dele = Expression.Lambda(ctx.Expression).Compile();
                    obj = dele.DynamicInvoke();
                    exp = Expression.Constant(obj, ctx.ReturnType);
                }
                var constCtx = new ExpressionParseContext()
                {
                    Expression = exp
                };
                constCtx.Parents.AddRange(ctx.Parents);
                var index = ctx.Parent.Children.IndexOf(ctx);
                ctx.Parent.Children.Remove(ctx);
                ctx.Parent.Children.Insert(index, constCtx);
                //注意: 虽然这里进行了替换，但是原Expression树是没有替换的（只读），所以后续遍历时主要以ExpressionParseContext的树为准
            }
        }
        #endregion

        #region 将构建好的表达式树转成sql
        /// <summary>
        /// 将构建好的表达式树转成sql
        /// MemberAccess的尽头肯定是Parameter
        /// null: is not null
        /// enum:
        /// 扩展表:
        /// 扩展列:
        /// </summary>
        /// <returns></returns>
        public (string sql, IDataParameter[]) ConvertToSql(ExpressionParseContext ctx)
        {
            if (ctx.NodeType == ExpressionType.Constant)
            {
                if ((ctx.Expression as ConstantExpression).Value.To<bool>())
                {
                    return (null, new IDataParameter[] { });
                }
                else
                {
                    return ("1>1", new IDataParameter[] { });
                }
            }
            if (ctx.NodeType != ExpressionType.Lambda) throw new Exception("表达式树格式不正确!");
            if (ctx.Children.Count != 1) throw new Exception("表达式树格式不正确!");
            var dicAlias = new Dictionary<Type, string>();
            var paras = new List<IDataParameter>();

            _convertToSql(ctx.Children[0]);

            return (ctx.Children[0].SqlCache, paras.ToArray());
        }


        private void _convertToSql(ExpressionParseContext ctx)
        {
            if (_dicActs.ContainsKey(ctx.NodeType))
            {
                _dicActs[ctx.NodeType](ctx);
            }
            else
            {
                throw new Exception($"未识别的表达式类型:{ctx.Expression}!");
            }
        }

        void VisitConstant(ExpressionParseContext ctx)
        {
            var exp = ctx.Expression as ConstantExpression;
            if (exp.Value == null)
            {
                ctx.SqlCache = "null";
            }
            else if (exp.Value is string)
            {
                ctx.SqlCache = $"'{exp.Value.ToString().Replace("'", "''")}'";
            }
            else if (exp.Value.IsNumberic())
            {
                ctx.SqlCache = exp.Value.ToString();
            }
            else if (exp.Value is DateTime d)
            {
                ctx.SqlCache = $"'{d.ToString("yyyy-MM-dd HH:mm:ss.fff")}'";
            }
            else if (exp.Value is bool b)
            {
                ctx.SqlCache = b ? "1" : "0";
            }
        }

        private void VisitUnary(ExpressionParseContext ctx)
        {
            var op = _dicOp[ctx.NodeType];
            ctx.SqlCache = op;
            _convertToSql(ctx.Children[0]);
            ctx.SqlCache = $"({op} ({ctx.Children[1].SqlCache}))";
        }

        private void VisitAndAlso(ExpressionParseContext ctx)
        {
            _convertToSql(ctx.Children[0]);
            _convertToSql(ctx.Children[1]);
            if (ctx.Children[0].SqlCache == "1")
            {
                //忽略掉左边
                ctx.SqlCache = $"({ctx.Children[1].SqlCache})";
            }
            else if (ctx.Children[1].SqlCache == "1")
            {
                //忽略掉右边
                ctx.SqlCache = $"({ctx.Children[0].SqlCache})";
            }
            else
            {
                //均不能忽略
                ctx.SqlCache = $"({ctx.Children[0].SqlCache} and {ctx.Children[1].SqlCache})";
            }
        }

        private void VisitOrElse(ExpressionParseContext ctx)
        {
            _convertToSql(ctx.Children[0]);
            _convertToSql(ctx.Children[1]);
            if (ctx.Children[0].SqlCache == "0")
            {
                //忽略掉左边
                ctx.SqlCache = $"({ctx.Children[1].SqlCache})";
            }
            else if (ctx.Children[1].SqlCache == "0")
            {
                //忽略掉右边
                ctx.SqlCache = $"({ctx.Children[0].SqlCache})";
            }
            else
            {
                //均不能忽略
                ctx.SqlCache = $"({ctx.Children[0].SqlCache} or {ctx.Children[1].SqlCache})";
            }
        }

        private void VisitNot(ExpressionParseContext ctx)
        {
            _convertToSql(ctx.Children[0]);
            ctx.SqlCache = $"( not ({ctx.Children[0].SqlCache}))";
        }

        private void VisitBinary(ExpressionParseContext ctx)
        {
            var op = _dicOp[ctx.NodeType];
            ctx.SqlCache = op;
            _convertToSql(ctx.Children[0]);
            _convertToSql(ctx.Children[1]);
            ctx.SqlCache = $"({ctx.Children[0].SqlCache} {op} {ctx.Children[1].SqlCache})";
        }

        private void VisitMemberAccess(ExpressionParseContext ctx)
        {
            //先取名字
            //p.IntNullable.Value : 
            var exp = ctx.Expression as MemberExpression;
            if (exp.Member.MemberType != System.Reflection.MemberTypes.Property) throw new Exception($"必须定义为属性: {exp.Member}!");
            var prop = exp.Member as PropertyInfo;
            if (prop.Name == "Value" && prop.DeclaringType.Name == "Nullable`1")
            {
                //忽略掉这个属性
                _convertToSql(ctx.Children[0]);
                ctx.SqlCache = ctx.Children[0].SqlCache;
            }
            else
            {
                #region 扩展列
                var extendColumn = prop.GetCustomAttribute<MapExtendColumnAttribute>();
                if (extendColumn != null)
                {
                    //扩展列
                    return;
                }
                var extendColumnJoin = prop.GetCustomAttribute<MapExtendColumn_JoinAttribute>();
                if (extendColumnJoin != null)
                {
                    //扩展列
                    return;
                }
                var extendColumnSql = prop.GetCustomAttribute<MapExtendColumn_SqlAttribute>();
                if (extendColumnSql != null)
                {
                    //扩展列
                    return;
                }
                #endregion

                #region 扩展表

                #endregion

                #region 正常列
                var colname = "";
                var clsType = prop.DeclaringType;
                var attr = prop.GetCustomAttribute<MapColumnAttribute>();
                if (attr is MapRawAttribute) throw new Exception("过滤条件中不支持[MapRaw]特性标记!");
                colname = attr?.Name;
                if (colname.IsNullOrEmptyOrWhiteSpace()) colname = prop.Name;
                ctx.SqlCache = $"[{ctx.Alias}].[{colname}]";


                #endregion
            }
        }

        private void VisitParameter(ExpressionParseContext ctx)
        {

        }

        #endregion

        public bool IsBinary(Expression exp)
        {
            return exp is BinaryExpression;
        }
        public bool IsUnary(Expression exp)
        {
            return exp is UnaryExpression;
        }
        public bool IsConditional(Expression exp)
        {
            return exp is ConditionalExpression;
        }



        private bool isSwitch(ExpressionType expressionType)
        {
            switch (expressionType)
            {
                #region 逻辑运算符 仅支持 &&、||、!这三种
                case ExpressionType.AndAlso: // "&&"
                case ExpressionType.OrElse: // "||"
                case ExpressionType.Not:// "!"
                    {
                        return true;
                    }
                case ExpressionType.And:// "&"
                case ExpressionType.Or:// "|"
                case ExpressionType.AndAssign://"&=" 不支持(不能含赋值操作)

                    {
                        return false;
                    }
                #endregion
                #region 算术运算符
                case ExpressionType.Add:// "+"
                case ExpressionType.AddChecked:// "+"
                case ExpressionType.Divide:// "/"
                case ExpressionType.Subtract:// "-"
                case ExpressionType.Modulo:// "%"
                case ExpressionType.Multiply:// "*"
                case ExpressionType.MultiplyChecked:// "*"
                case ExpressionType.Negate:// "-" 算术求反运算，如 (-a)。
                case ExpressionType.NegateChecked:// "-" 算术求反运算，如 (-a)。
                    {
                        return true;
                    }
                case ExpressionType.UnaryPlus:// 不认识不支持
                case ExpressionType.Increment://不认识不支持
                case ExpressionType.Decrement://不认识不支持
                case ExpressionType.Assign://"=" (不能含赋值操作)
                case ExpressionType.PreIncrementAssign://"++i" (不能含赋值操作)
                case ExpressionType.PreDecrementAssign://"--i" 自减不支持(不能含赋值操作)
                case ExpressionType.PostIncrementAssign://"i++" 自增不支持(不能含赋值操作)
                case ExpressionType.PostDecrementAssign://"i--" 自减不支持(不能含赋值操作)
                case ExpressionType.AddAssign:// "+=" 不支持(不能含赋值操作)
                case ExpressionType.AddAssignChecked:// "+=" 不支持(不能含赋值操作)
                case ExpressionType.DivideAssign:// "/=" 不支持(不能含赋值操作)
                case ExpressionType.SubtractAssign:// "-=" 不支持(不能含赋值操作)
                case ExpressionType.SubtractAssignChecked:// "-=" 不支持(不能含赋值操作)
                case ExpressionType.MultiplyAssign://"*=" 不支持(不能含赋值操作)
                case ExpressionType.MultiplyAssignChecked://"*=" 不支持(不能含赋值操作)
                case ExpressionType.PowerAssign://"^=" 不支持(不能含赋值操作)
                case ExpressionType.ModuloAssign://"%=" 不支持(不能含赋值操作)
                case ExpressionType.RightShiftAssign://">>=" 不支持(不能含赋值操作)
                case ExpressionType.LeftShiftAssign://"<<=" 不支持(不能含赋值操作)
                case ExpressionType.ExclusiveOrAssign://"^=" 不支持(不能含赋值操作)
                    {
                        return false;
                    }
                #endregion
                #region 布尔运算符
                case ExpressionType.GreaterThan:// ">"
                case ExpressionType.GreaterThanOrEqual:// ">="
                case ExpressionType.LessThan:// "<"
                case ExpressionType.LessThanOrEqual:// "<="
                case ExpressionType.Equal:// "=="
                case ExpressionType.NotEqual:// "!="
                    {
                        return true;
                    }
                #endregion
                #region 其他
                case ExpressionType.ArrayLength:// arr.Length
                case ExpressionType.ArrayIndex:// arr[1]
                    {
                        return true;
                    }
                #endregion

                default:
                    {
                        return false;
                    }
            }
        }
    }
}
